﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using Expense.Tracker;

namespace Expense_Tracker_System
{
    public class aHelperModule
    {
        #region Declarations
        ExpenseTracker tracker;
        //MainExpenseForm mainForm;
        
        TreeView _iTreeView;
        ImageList _iImageList;
        #endregion

        #region Properties

        private int _expenseID;
        public int ExpenseID
        {
            get { return _expenseID; }
            set { _expenseID = value; }
        }

        private string _expenseType;
        public string ExpenseType
        {
            get { return _expenseType; } 
            set { _expenseType = value; } 
        }

        private DateTime _expenseDate;
        public DateTime ExpenseDate 
        {
            get { return _expenseDate; }
            set { _expenseDate = value; } 
        }

        private string _expenseReceipt;
        public string ExpenseReceipt 
        {
            get { return _expenseReceipt; }
            set { _expenseReceipt = value; } 
        }

        private decimal _expenseValue;
        public decimal ExpenseValue 
        {
            get { return _expenseValue; }
            set { _expenseValue = value; }
        }
        
        #endregion

        #region Public Methods
        
        public int SaveExpense()
        {
            tracker = new ExpenseTracker(_expenseType, _expenseDate, _expenseReceipt, _expenseValue);
            return tracker.SaveExpense();
        }

        public int SaveSettings(CheckBox cbSettings)
        {
            tracker = new ExpenseTracker(cbSettings.Checked, Convert.ToInt32(cbSettings.Tag));
            return tracker.SaveSettings();
        }

        public int SaveTypes(string strTypeValue)
        {
            tracker = new ExpenseTracker(strTypeValue);
            return tracker.SaveTypes();
        }

        public void DisplayTreeValues(TreeView myTreeView, ImageList myImageList)
        {
            DataTable treeDT = new DataTable();
            TreeNode baseNode = new TreeNode();
            TreeNode yearNode = new TreeNode();
            TreeNode monthNode = new TreeNode();
            TreeNode dailyNode = new TreeNode();
            string yearValue = "";
            string monthValue = "";

            try
            {
                treeDT = TreeExpenseDT();

                myTreeView.Nodes.Clear();

                baseNode = myTreeView.Nodes.Add("Expense Dates", "Expense Dates", 0, 0);
                foreach (DataRow dr in treeDT.Rows)
                {
                    DateTime dtValue = Convert.ToDateTime(dr["ExpenseDate"].ToString());
                    
                    if (yearValue == dtValue.Year.ToString())
                    {
                        if (monthValue == ReturnMonth(dtValue.Month.ToString()))
                        {
                            dailyNode = monthNode.Nodes.Add(dtValue.ToShortDateString(), dtValue.ToShortDateString(), 1, 1);
                        }
                        else
                        {
                            monthNode = yearNode.Nodes.Add(ReturnMonth(dtValue.Month.ToString()), ReturnMonth(dtValue.Month.ToString()), 1, 1);
                            dailyNode = monthNode.Nodes.Add(dtValue.ToShortDateString(), dtValue.ToShortDateString(), 1, 1);
                        }
                    }
                    else
                    {
                        yearNode = baseNode.Nodes.Add(dtValue.Year.ToString(), dtValue.Year.ToString(), 1, 1);

                        if (monthValue == ReturnMonth(dtValue.Month.ToString()))
                        {
                            dailyNode = monthNode.Nodes.Add(dtValue.ToShortDateString(), dtValue.ToShortDateString(), 1, 1);
                        }
                        else
                        {
                            monthNode = yearNode.Nodes.Add(ReturnMonth(dtValue.Month.ToString()), ReturnMonth(dtValue.Month.ToString()), 1, 1);
                            dailyNode = monthNode.Nodes.Add(dtValue.ToShortDateString(), dtValue.ToShortDateString(), 1, 1);
                        }
                    }

                    yearValue = dtValue.Year.ToString();
                    monthValue = ReturnMonth(dtValue.Month.ToString());
                }
                myTreeView.ExpandAll();
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                _iTreeView = myTreeView;
                _iImageList = myImageList;
            }
        }

        public void DisplayDataGridTabValues(DateTime dtmExpenseDate, TabControl myTabControl)
        {
            TabPage expenseTab = new TabPage();
            DataGridView expenseGrid = new DataGridView();

            expenseGrid = GridTabValues(dtmExpenseDate);

            expenseTab.Text = "Grid View: " + dtmExpenseDate.ToShortDateString();
            expenseTab.BackColor = Color.White;
            expenseTab.Controls.Add(expenseGrid);

            myTabControl.TabPages.Add(expenseTab);
            myTabControl.SelectedTab = expenseTab;
        }

        public void DisplayGraphicalTabValues(string strMonth, string strYear, TabControl myTabControl)
        {
            TabPage expenseTab = new TabPage();
            Chart expenseChart = new Chart();
            TextBox expenseText = new TextBox();

            expenseChart = ChartTabValues(strMonth, strYear);
            expenseText = TextTabValues(strMonth, strYear);

            expenseTab.Text = "Graph View: " + ReturnMonth(strMonth);
            expenseTab.BackColor = Color.White;
            expenseTab.Controls.Add(expenseText);
            expenseTab.Controls.Add(expenseChart);

            myTabControl.TabPages.Add(expenseTab);
            myTabControl.SelectedTab = expenseTab;
        }

        public DataGridView GridTabValues(DateTime dtmExpenseDate)
        {
            DataGridView expenseGrid = new DataGridView();
            DataTable expenseDT = new DataTable();

            _expenseDate = dtmExpenseDate;
            expenseDT = DisplayExpenseDT();

            expenseGrid.DataSource = null;
            expenseGrid.DataSource = expenseDT;
            expenseGrid.Dock = DockStyle.Fill;
            expenseGrid.BackgroundColor = Color.White;
            expenseGrid.GridColor = Color.White;
            expenseGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            expenseGrid.AllowUserToAddRows = false;
            expenseGrid.AllowUserToDeleteRows = false;
            expenseGrid.AllowUserToOrderColumns = false;
            expenseGrid.AllowUserToResizeColumns = false;
            expenseGrid.AllowUserToResizeRows = false;
            expenseGrid.ShowEditingIcon = false;
            expenseGrid.ReadOnly = true;
            expenseGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

            return expenseGrid;
        }

        public Chart ChartTabValues(string strMonth, string strYear)
        {
            Chart expenseChart = new Chart();
            ChartArea chartArea = new ChartArea();
            Series series = new Series();
            List<DateTime> xValues = new List<DateTime>();
            List<Double> yValues = new List<Double>();

            TextBox expenseText = new TextBox();
            Double maxAccountLevel = int.MinValue;

            DataTable expenseDT = new DataTable();

            string message = "";
            string startMonth = "";
            string endMonth = "";

            startMonth = strMonth + "/1/" + strYear;
            endMonth = strMonth + "/" + ReturnMonthEndValues(strMonth) + "/" + strYear;

            _expenseType = startMonth;
            _expenseReceipt = endMonth;
            expenseDT = GraphExpenseDT();
            expenseDT = ReturnMonthDataTable(expenseDT, strMonth, strYear);

            int DTrowlength = expenseDT.Rows.Count;

            for (int i = 0; i < DTrowlength; i++)
            {
                DateTime expenseDate = Convert.ToDateTime(expenseDT.Rows[i]["ExpenseDate"].ToString());
                Double expenseSum = Convert.ToDouble(expenseDT.Rows[i]["ExpenseSum"].ToString());

                yValues.Add(expenseSum);
                xValues.Add(expenseDate);
            }

            maxAccountLevel = yValues.Max();

            foreach (DataRow item in expenseDT.Rows)
            {
                if (Convert.ToDouble(item["ExpenseSum"].ToString()) == maxAccountLevel)
                {
                    message = "The date '" + Convert.ToDateTime(item["ExpenseDate"].ToString()).ToShortDateString()
                        + "' has the highest expensed value which is P" + maxAccountLevel.ToString() + ".";
                }
            }

            IEnumerable<DateTime> xVal = xValues.AsEnumerable();
            IEnumerable<Double> yVal = yValues.AsEnumerable();

            chartArea.AxisX.LabelStyle.Format = "MM/dd";
            chartArea.AxisX.MajorGrid.LineColor = Color.LightGray;
            chartArea.AxisX.MinorGrid.LineColor = Color.LightGray;
            chartArea.AxisY.MajorGrid.LineColor = Color.LightGray;
            chartArea.AxisY.MinorGrid.LineColor = Color.LightGray;
            chartArea.AxisX.LabelStyle.Font = new Font("Consolas", 4);
            chartArea.AxisY.LabelStyle.Font = new Font("Consolas", 4);
            chartArea.AxisX.IsLabelAutoFit = true;
            chartArea.AxisY.IsLabelAutoFit = true;
            chartArea.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
            chartArea.AxisY.IntervalAutoMode = IntervalAutoMode.VariableCount;
            expenseChart.ChartAreas.Add(chartArea);

            series.Name = ReturnMonth(strMonth) + "  " + strYear;
            series.ChartType = SeriesChartType.FastLine;
            series.XValueType = ChartValueType.DateTime;
            series.IsValueShownAsLabel = true;
            expenseChart.Series.Add(series);
            expenseChart.Series[ReturnMonth(strMonth) + "  " + strYear].Points.DataBindXY(xVal, yVal);

            expenseChart.BringToFront();
            expenseChart.Dock = DockStyle.Fill;

            expenseText.Text = message;
            expenseText.BackColor = Color.White;
            expenseText.ReadOnly = true;
            expenseText.Dock = DockStyle.Bottom;

            return expenseChart;
        }

        public TextBox TextTabValues(string strMonth, string strYear)
        {
            TextBox expenseText = new TextBox();
            Double maxAccountLevel = int.MinValue;
            List<Double> yValues = new List<Double>();
            DataTable expenseDT = new DataTable();

            string message = "";
            string startMonth = "";
            string endMonth = "";

            startMonth = strMonth + "/1/" + strYear;
            endMonth = strMonth + "/" + ReturnMonthEndValues(strMonth) + "/" + strYear;

            _expenseType = startMonth;
            _expenseReceipt = endMonth;
            expenseDT = GraphExpenseDT();
            expenseDT = ReturnMonthDataTable(expenseDT, strMonth, strYear);

            int DTrowlength = expenseDT.Rows.Count;

            for (int i = 0; i < DTrowlength; i++)
            {
                Double expenseSum = Convert.ToDouble(expenseDT.Rows[i]["ExpenseSum"].ToString());

                yValues.Add(expenseSum);
            }

            maxAccountLevel = yValues.Max();

            foreach (DataRow item in expenseDT.Rows)
            {
                if (Convert.ToDouble(item["ExpenseSum"].ToString()) == maxAccountLevel)
                {
                    message = "The date '" + Convert.ToDateTime(item["ExpenseDate"].ToString()).ToShortDateString()
                        + "' has the highest expensed value which is P" + maxAccountLevel.ToString() + ".";
                }
            }

            expenseText.Text = message;
            expenseText.BackColor = Color.White;
            expenseText.ReadOnly = true;
            expenseText.Dock = DockStyle.Bottom;

            return expenseText;
        }

        public void LoadCheckBoxes(CheckBox MinToTray, CheckBox MaxAtStart, CheckBox RunAtStart)
        {
            bool _minTray, _maxStart, _runStart;
            DataTable dtSettings;

            dtSettings = SettingsDT();

            if (dtSettings != null)
            {
                _minTray = Convert.ToBoolean(dtSettings.Rows[0]["SettingsValue"].ToString()); //1
                _maxStart = Convert.ToBoolean(dtSettings.Rows[1]["SettingsValue"].ToString()); //2
                _runStart = Convert.ToBoolean(dtSettings.Rows[2]["SettingsValue"].ToString()); //3

                MinToTray.Checked = _minTray;
                MinToTray.Tag = dtSettings.Rows[0]["SettingsID"].ToString();

                MaxAtStart.Checked = _maxStart;
                MaxAtStart.Tag = dtSettings.Rows[1]["SettingsID"].ToString();

                RunAtStart.Checked = _runStart;
                RunAtStart.Tag = dtSettings.Rows[2]["SettingsID"].ToString();
            }

        }

        public void LoadComboBoxes(ComboBox ExpenseCombo)
        {
            DataTable typeDT = TypesDT();
            ExpenseCombo.Items.Clear();

            foreach (DataRow item in typeDT.Rows)
            {
                ExpenseCombo.Items.Add(item["TypeDesc"].ToString());
            }
        }

        public bool GetSettings(string strSettingsType)
        {
            bool _boolValue = false;
            string[] _strValues = strSettingsType.Split(':');
            DataTable dtSettings;
            dtSettings = SettingsDT();

            foreach (DataRow item in dtSettings.Rows)
            {
                if ((item["SettingsID"].ToString() == _strValues[0]) & (item["SettingsDesc"].ToString() == _strValues[1]))
                {
                    _boolValue = Convert.ToBoolean(item["SettingsValue"].ToString());
                }
            }

            return _boolValue;
        }

        public bool CheckTypes(string strTypeValue)
        {
            bool typeBool = true;
            string typeValue = strTypeValue.Trim();
            DataTable typeDT = TypesDT();

            foreach (DataRow item in typeDT.Rows)
            {
                if (item["TypeDesc"].ToString() == typeValue)
                    typeBool = false;
            }

            return typeBool;
        }

        public bool CheckSelectedValue(string strValue)
        {
            bool val = false;
            string[] value = strValue.Split(':');

            string months = "January|February|March|April|May|June|July|August|September|October|November|December";

            if (value.Length > 1)
            {
                if (months.Contains(value[1].ToString()) == true)
                    val = true;
                else
                    val = false;
            }
            
            return val;
        }
        #endregion

        #region Private Methods
        private DataTable SettingsDT()
        {
            tracker = new ExpenseTracker();
            return tracker.GetSettings();
        }

        private DataTable TypesDT()
        {
            tracker = new ExpenseTracker();
            return tracker.GetExpenseTypes();
        }

        private DataTable TreeExpenseDT()
        {
            tracker = new ExpenseTracker();
            return tracker.GetTreeExpense();
        }

        private DataTable DisplayExpenseDT()
        {
            tracker = new ExpenseTracker(_expenseDate);
            return tracker.GetDisplayExpense();
        }

        private DataTable GraphExpenseDT()
        {
            tracker = new ExpenseTracker(_expenseType, _expenseReceipt);
            return tracker.GetGraphExpense();
        }

        private DataTable CreateMonthDataTable()
        {
            DataTable monthDT = new DataTable();

            monthDT.Columns.Add("ExpenseDate");
            monthDT.Columns.Add("ExpenseSum");

            return monthDT;
        }

        private DataTable ReturnMonthDataTable(DataTable expenseDT, String strMonth, String strYear)
        {
            DataTable monthDT = new DataTable();
            DataRow monthRW = null;

            int monthLong = Convert.ToInt32(ReturnMonthEndValues(strMonth)) + 1;

            monthDT = CreateMonthDataTable();

            try
            {
                for (int i = 1; i < monthLong; i++)
                {
                    monthRW = monthDT.NewRow();
                    monthRW["ExpenseDate"] = Convert.ToDateTime(strMonth + "/" + i + "/" + strYear).ToString();
                    monthRW["ExpenseSum"] = "0";
                    monthDT.Rows.Add(monthRW);
                }

                foreach (DataRow item in expenseDT.Rows)
                {
                    string eDate = item["ExpenseDate"].ToString();
                    string eValue = item["ExpenseSum"].ToString();
                    
                    IEnumerable<DataRow> dRows = monthDT.Rows.Cast<DataRow>().Where(r => r["ExpenseDate"].ToString() == eDate);
                    dRows.ToList().ForEach(r => r.SetField("ExpenseSum", eValue));
                }
            }
            catch (Exception)
            {
                //throw;
            }
            finally
            {
                monthRW = null;
            }

            return monthDT;
        }

        private string ReturnMonth(string strMonth)
        {
            string MonthName = "";

            if (strMonth == "1")
                MonthName = "1:January";
            else if (strMonth == "2")
                MonthName = "2:February";
            else if (strMonth == "3")
                MonthName = "3:March";
            else if (strMonth == "4")
                MonthName = "4:April";
            else if (strMonth == "5")
                MonthName = "5:May";
            else if (strMonth == "6")
                MonthName = "6:June";
            else if (strMonth == "7")
                MonthName = "7:July";
            else if (strMonth == "8")
                MonthName = "8:August";
            else if (strMonth == "9")
                MonthName = "9:September";
            else if (strMonth == "10")
                MonthName = "10:October";
            else if (strMonth == "11")
                MonthName = "11:November";
            else if (strMonth == "12")
                MonthName = "12:December";

                return MonthName;
        }

        private string ReturnMonthEndValues(string monthValue)
        {
            string MonthEnd = ""; 

            if (monthValue == "1")
                MonthEnd = "31";
            else if (monthValue == "2")
                MonthEnd = "28";
            else if (monthValue == "3")
                MonthEnd = "31";
            else if (monthValue == "4")
                MonthEnd = "30";
            else if (monthValue == "5")
                MonthEnd = "31";
            else if (monthValue == "6")
                MonthEnd = "30";
            else if (monthValue == "7")
                MonthEnd = "31";
            else if (monthValue == "8")
                MonthEnd = "31";
            else if (monthValue == "9")
                MonthEnd = "30";
            else if (monthValue == "10")
                MonthEnd = "31";
            else if (monthValue == "11")
                MonthEnd = "30";
            else if (monthValue == "12")
                MonthEnd = "31";

            return MonthEnd;
        }

        #endregion
    }
}
